#ifndef GRAMMARRAWSTRUCTS_H
#define GRAMMARRAWSTRUCTS_H

#include <string>
#include <boost/fusion/include/adapt_struct.hpp>

namespace GST{
namespace Parsers{

//
// data classes (structs)
//
struct RawPoint3
{
    double x;
	double y;
	double z;

	RawPoint3(){}
	RawPoint3(const double& x, const double& y, const double& z)
		: x(x), y(y), z(z)
	{}
};

struct NameValuePair
{
    std::string name;
    std::string value;
};

struct IdxTriangle
{
    unsigned long v1;
	unsigned long v2;
	unsigned long v3;

	IdxTriangle() {}
	IdxTriangle(const unsigned long& v1, const unsigned long& v2, const unsigned long& v3)
		: v1(v1), v2(v2), v3(v3)
	{}
};

struct IdxTetrahedron
{
    unsigned long v1;
	unsigned long v2;
	unsigned long v3;
	unsigned long v4;

	IdxTetrahedron() {}
	IdxTetrahedron(const unsigned long& v1, const unsigned long& v2, const unsigned long& v3, const unsigned long& v4)
		: v1(v1), v2(v2), v3(v3), v4(v4)
	{}
};


struct GridOrientation {
	RawPoint3 x_axis;
	RawPoint3 y_axis;
	RawPoint3 z_axis;
	GridOrientation(const RawPoint3& x_axis=RawPoint3(), const RawPoint3& y_axis=RawPoint3(), const RawPoint3& z_axis=RawPoint3())
		: x_axis(x_axis), y_axis(y_axis), z_axis(z_axis)
	{}
};

struct GridSize {
	unsigned int x;
	unsigned int y;
	unsigned int z;
	GridSize(const unsigned int& x=0, const unsigned int& y=0, const unsigned int& z=0)
		: x(x), y(y), z(z)
	{}
};
/**
*	This struct describes the position, orientation and size (in terms of elements) of a Grid.
*	Axis-Order is defined as X, Y, Z
*	'position' describes the origin-point of the outer border of the Grid as a x,y,z coordinate.
*	'orientation' describes the orientation and length of a single grid-cell in x,y,z length.
*	'size' describes the amount of grid-cells in x,y and z direction respectively.
*/
struct GridDescription {

	RawPoint3 position;
	GridSize size;
	GridOrientation orientation;

	GridDescription(const RawPoint3& position = RawPoint3(), const GridOrientation& orientation = GridOrientation(), const GridSize& size = GridSize()) : position(position), orientation(orientation), size(size) {};
};

}// namespace Parsers
}// namespace GST

//
// data classes as boost.fusion struct (must be in global namespace)
//
BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::RawPoint3,
    (double, x)
	(double, y)
	(double, z)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::NameValuePair,
    (std::string, name)
    (std::string, value)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::IdxTriangle,
	(unsigned long, v1)
	(unsigned long, v2)
	(unsigned long, v3)
)

BOOST_FUSION_ADAPT_STRUCT(
	GST::Parsers::IdxTetrahedron,
	(unsigned long, v1)
	(unsigned long, v2)
	(unsigned long, v3)
	(unsigned long, v4)
)

#endif //GRAMMARRAWSTRUCTS_H